from src.baseapp.controller.baseController import BaseController
from src.baseapp.core.device.device.DeviceFactory import DeviceFactory
from src.baseapp.model.BaseOrmOpeator import OrmOperator
from src.baseapp.model.deviceServiceModel.deviceModel import DeviceModel
from src.baseapp.model.deviceServiceModel.deviceTypeSignalingMappingModel import DeviceTypeSignalingMappingModel
from src.baseapp.model.deviceServiceModel.deviceSignalingModel import SignalingModel
from typing import List


class DeviceController(BaseController):
    def __init__(self):
        super().__init__()
        self.orm = OrmOperator(DeviceModel)
        self.device_type_signaling_mapping_orm = OrmOperator(DeviceTypeSignalingMappingModel)
        self.signaling_orm = OrmOperator(SignalingModel)



    def add_device(self, device_info: dict) -> tuple:
        """
        添加设备
        :param device_info: 设备信息
        :return:
        """
        response = self.response_data()
        try:
            device = DeviceModel(**device_info)
            self.orm.insert_data(device)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def delete_device(self, device_ids: List[int]) -> tuple:
        """
        删除设备
        :param device_ids: 设备id
        :return:
        """
        response = self.response_data()
        try:
            devices: List[DeviceModel] = self.orm.in_here(DeviceModel.device_id, device_ids).equal(DeviceModel.is_delete, 0).get_all()
            for device in devices:
                device.is_delete = 1
            self.orm.update_data(devices)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def update_device(self, device_ids: List[int], modify_info: dict) -> tuple:
        """
        更新设备
        :param device_ids: 设备id
        :param modify_info: 修改信息
        :return:
        """
        response = self.response_data()
        try:
            devices: List[DeviceModel] = self.orm.in_here(DeviceModel.device_id, device_ids).equal(DeviceModel.is_delete, 0).get_all()
            for device in devices:
                for key, value in modify_info.items():
                    setattr(device, key, value)
            self.orm.update_data(devices)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def get_device_list(self, conditions: dict) -> tuple:
        """
        获取设备列表
        :param conditions: 查询条件
        :return:
        """
        response = self.response_data()
        field_condition_mapping = {
            "device_id": DeviceModel.device_id,
            "device_name": DeviceModel.device_name,
            "imei": DeviceModel.imei,
            "model_id": DeviceModel.model_id,
            "device_status": DeviceModel.device_status,
            "create_time": DeviceModel.create_time,
            "update_time": DeviceModel.update_time,
        }
        try:
            self.orm.equal(DeviceModel.is_delete, 0)

            for key, value in conditions.items():
                if key in ("device_name", "imei"):
                    self.orm.like(field_condition_mapping[key], value)
                elif key in ("model_id", "device_status"):
                    self.orm.in_here(field_condition_mapping[key], value)
                elif key in ("create_time", "update_time"):
                    self.orm.between(field_condition_mapping[key], *value)
                else:
                    self.orm.equal(field_condition_mapping[key], value)

            devices: List[DeviceModel] = self.orm.get_all()
            response.data['devices'] = [
                {
                    'device_id': device.device_id,
                    'device_name': device.device_name,
                    'model_id': device.model_id,
                    "imei": device.imei,
                    'device_status': device.device_status,
                    'create_time': device.create_time,
                    'update_time': device.update_time,
                }
                for device in devices
            ]
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def get_device_info(self, device_id: int) -> tuple:
        """
        获取设备信息
        :param device_id: 设备id
        :return:
        """
        response = self.response_data()
        try:
            device: DeviceModel = self.orm.equal(DeviceModel.device_id, device_id).equal(DeviceModel.is_delete,0).get_one()
            device_signs: List[DeviceTypeSignalingMappingModel]\
                = OrmOperator(DeviceTypeSignalingMappingModel)\
                .equal(DeviceTypeSignalingMappingModel.device_type_id, device.model_id)\
                .get_all()

            response.data['device'] = {
                "device_id": device.device_id,
                "device_name": device.device_name,
                "model_id": device.model_id,
                "imei": device.imei,
                "ip": device.ip,
                "port": device.port,
                "device_status": device.device_status,
                "device_signs": [
                    {
                        "signaling_id": device_sign.signaling_id,
                        "signaling_name": SignalingModel.query.filter(SignalingModel.signaling_id == device_sign.signaling_id).first().signaling_name
                    }
                    for device_sign in device_signs
                ],
                "create_time": device.create_time,
                "update_time": device.update_time,

            }
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def active_device(self, device_id: int) -> tuple:
        """
        激活设备
        :param device_id: 设备id
        :return:
        """
        response = self.response_data()
        try:
            device: DeviceModel = self.orm.equal(DeviceModel.device_id, device_id).equal(DeviceModel.is_delete, 0).get_one()
            device.device_status = 0

            # 激活设备
            device = DeviceFactory.create_device(device.device_name, device.imei, device.ip, device.port, device.model_id)
            device.active()
            # 激活成功后，才更新设备状态
            self.orm.update_data(device)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def deactive_device(self, device_id: int) -> tuple:
        """
        停用设备
        :param device_id: 设备id
        :return:
        """
        response = self.response_data()
        try:
            device: DeviceModel = self.orm.equal(DeviceModel.device_id, device_id).equal(DeviceModel.is_delete, 0).get_one()
            device.device_status = 1

            # 停用设备
            DeviceFactory.remove_device(device.imei)
            # 停用成功后，才更新设备状态
            self.orm.update_data(device)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def send_message(self, device_id: int, sign_id: int, args: List[dict[str, str]]) -> tuple:
        """
        发送消息
        :param device_id: 设备id
        :param sign_id: 信令id
        :param args: 参数
        :return:
        """
        response = self.response_data()
        try:
            device = self.orm.equal(DeviceModel.device_id, device_id).equal(DeviceModel.is_delete, 0).get_one()
            device: DeviceFactory.BaseDevice = DeviceFactory.get_device(device.imei)
            message: SignalingModel = self.signaling_orm.equal(SignalingModel.signaling_id, sign_id).equal(SignalingModel.is_delete,
                                                                                           0).get_one().signaling_message
            if not device:
                response.code = 400
                response.msg = "device not found"
            elif not message:
                response.code = 400
                response.msg = "signaling not found"
            else:
                device.send_message(message, args)
        except Exception as e:
            response.code = 500
            response.msg = str(e)

        return response.code, response.to_dict

    def get_message_list(self, device_id: int) -> tuple:
        """
        获取消息列表
        :param device_id: 设备id
        :return:
        """
        response = self.response_data()
        try:
            device = self.orm.equal(DeviceModel.device_id, device_id).equal(DeviceModel.is_delete, 0).get_one()
            device: DeviceFactory.BaseDevice = DeviceFactory.get_device(device.imei)

            if not device:
                response.code = 400
                response.msg = "device not found"
            else:
                response.data['messages'] = device.messages
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict
